<?php
declare(strict_types=1);

namespace app\curd\command;

use think\console\Input;
use think\console\Output;
use think\console\input\Option;
use think\console\input\Argument;
use think\console\command\make\Controller;

/**
 * 增强版控制器生成
 */
class Ddc extends Controller
{
    protected $type = "DDc";
    protected function configure()
    {
        // 指令配置
        $this->setName('xcurd:c')
            ->addArgument('name', Argument::REQUIRED, "控制器名，命名采用驼峰法（首字母大写）")
            ->addArgument('modelname', Argument::REQUIRED, "用于curd的模型名，命名采用驼峰法（首字母大写）")
            ->setDescription('生成控制器(格式：app@Controller Model) 控制器和模型名都要采用驼峰法（首字母大写）');
    }

    protected function getStub(): string
    {
        $stubPath = __DIR__ . DIRECTORY_SEPARATOR . 'stubs' . DIRECTORY_SEPARATOR;

        return $stubPath . 'controller.stub';
    }

    protected function execute(Input $input, Output $output)
    {
        $name = trim($input->getArgument('name'));

        $modelname = trim($input->getArgument('modelname'));

        [$appname, $Controllername] = explode('@', $name);

        $classname = $this->getClassName($name);

        $pathname = $this->getPathName($classname);

        if (is_file($pathname)) {
            $output->writeln('<error>' . $this->type . ':' . $classname . ' already exists!</error>');
            return false;
        }

        if (!is_dir(dirname($pathname))) {
            mkdir(dirname($pathname), 0755, true);
        }

        file_put_contents($pathname, $this->buildClassx($classname, $appname, $modelname));

        $output->writeln('<info>' . $this->type . ':' . $classname . ' created successfully.</info>');
    }

    /**
     * 控制器带默认模型curd生成
     * @param string $name 控制器名
     * @param string $modelname 模型名
     * @return array|string
     */
    protected function buildClassx(string $name, string $appname, string $modelname)
    {
        $stub = file_get_contents($this->getStub());

        $namespace = trim(implode('\\', array_slice(explode('\\', $name), 0, -1)), '\\');

        $class = str_replace($namespace . '\\', '', $name);

        return str_replace(['{%className%}', '{%actionSuffix%}', '{%namespace%}', '{%app_namespace%}', '{%appname%}', '{%modelname%}'], [
            $class,
            $this->app->config->get('route.action_suffix'),
            $namespace,
            $this->app->getNamespace(),
            $appname,
            $modelname,
        ], $stub);
    }
}
